package eteam.aps.common.helper;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

/**
 *
 */
public class JwtUtils {
    /**
     * token秘钥，请勿泄露
     */
    public static final String SECRET = "grt_secret";
    /**
     * token 过期时间: 1天
     */
    public static final int calendarField = Calendar.HOUR;
    public static final int calendarInterval = 1 * 24;

    /**
     * JWT生成Token
     * JWT构成: header, payload, signature
     *
     * @param user_id:     唯一ID，用户Id，user_id, 参数user_id不可传空
     * @param user_data:   用户信息，Json字符串
     * @param client_type: 客户端类型，授权平台
     * @param day_span:    token有效时间跨度，单位小时
     * @return: Token字符串
     */
    public static String buildToken(String user_id, String user_data, String client_type, int day_span) throws Exception {
        // header Map
        Map<String, Object> map = new HashMap<>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        // sign time
        Date iatDate = new Date();
        // expire time
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(calendarField, day_span > 0 ? day_span : calendarInterval);
        Date expiresDate = nowTime.getTime();
        //// 获取签名时候使用的密钥
        //SecretKey secretKey = generalKey();
        //.signWith(signatureAlgorithm, secretKey)
        // build token
        String token = JWT.create()
                .withHeader(map) // header
                .withKeyId(user_id) // KeyId
                .withJWTId(user_id) // 唯一ID
                .withIssuer("grt_admin") // 签发人
                //.withAudience() // 使用人
                //.withSubject() // 主题
                .withClaim("userid", user_id) // userid
                .withClaim("data", user_data) // payload
                .withClaim("platform", client_type)
                .withIssuedAt(iatDate) // sign time
                .withExpiresAt(expiresDate) // expire time
                .sign(Algorithm.HMAC256(SECRET)); // signature
        return token;
    }

    /**
     * JWT解密Token
     *
     * @param token: 用户Token信息
     * @return: 用户信息
     */
    public static Map<String, Claim> verifyToken(String token) throws Exception {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt = verifier.verify(token);
        //String userInfo = jwt.getClaim("data").asString();
        return jwt.getClaims();
    }

    /**
     * JWT解密Token
     *
     * @param token: 用户Token信息
     * @return: 用户信息
     */
    public static String verifyTokenRetJson(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            DecodedJWT jwt = verifier.verify(token);
            return jwt.getClaim("data").asString();
        } catch (Exception e) {
            e.printStackTrace();
            return "{}";
        }
    }
    
    

    /**
     * 生成加密后的秘钥 secretKey
     *
     * @return: 秘钥
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getDecoder().decode(SECRET);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }
    
    /**
     * JWT解密Token
     *
     * @param token: 用户Token信息
     * @return: 用户信息
     */
    public static String verifyTokenRetUserId(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            DecodedJWT jwt = verifier.verify(token);
            return jwt.getClaim("userid").asString();
        } catch (Exception e) {
            e.printStackTrace();
            return "{}";
        }
    }
}